﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

using Rockfan.Framework;
using Rockfan.Framework.Graphics;

namespace Rockfan.Framework.Entities
{
    public sealed class PlayNote : Sprite
    {
        #region Properties

        /// <summary>
        /// Gets or Sets the Texture info used for this object during the normal state
        /// </summary>
        public TextureInfo NormalTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Hopo Note
        /// </summary>
        public TextureInfo HopoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Tapo Note
        /// </summary>
        public TextureInfo TapoTexture { get; set; }
        
        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Note
        /// </summary>
        public TextureInfo DeadTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Hopo Note
        /// </summary>
        public TextureInfo DeadHopoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Tapo Note
        /// </summary>
        public TextureInfo DeadTapoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Power Note
        /// </summary>
        public TextureInfo DeadPowerTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Power Hopo Note
        /// </summary>
        public TextureInfo DeadPowerHopoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Dead Power Tapo Note
        /// </summary>
        public TextureInfo DeadPowerTapoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Power Note
        /// </summary>
        public TextureInfo PowerTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Tapo Power Note
        /// </summary>
        public TextureInfo PowerHopoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the Texture info used for a Tapo Power Note
        /// </summary>
        public TextureInfo PowerTapoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdriveTexture { get; set; }

        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdriveHopoTexture { get; set; }
        
        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdriveTapoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdrivePowerTexture { get; set; }

        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdrivePowerHopoTexture { get; set; }

        /// <summary>
        /// Gets or Sets the texture info used for this object during the overdrive state
        /// </summary>
        public TextureInfo OverdrivePowerTapoTexture { get; set; }
                
        /// <summary>
        /// Gets or Sets the Note type for this object
        /// </summary>
        public NoteType NoteType { get; set; }

        /// <summary>
        /// Gets a value indicating whether this note is currently a Hopo note
        /// </summary>
        public bool IsHopo
        {
            get { return (NoteType & NoteType.Hopo) == NoteType.Hopo; }
        }

        /// <summary>
        /// Gets a value indicating whether this note is currently a Tapo note
        /// </summary>
        public bool IsTapo
        {
            get { return (NoteType & NoteType.Tapo) == NoteType.Tapo; }
        }

        /// <summary>
        /// Gets a value indicating whether this note is currently dead
        /// </summary>
        public bool IsDead
        {
            get { return (NoteType & NoteType.Dead) == NoteType.Dead; }
        }

        /// <summary>
        /// Gets a value indicating whether this note is currently a power note
        /// </summary>
        public bool IsPower
        {
            get { return (NoteType & NoteType.Power) == NoteType.Power; }
        }

        /// <summary>
        /// Gets a value indicating whether this note is currently an overdrive note
        /// </summary>
        public bool IsOverdrive
        {
            get { return (NoteType & NoteType.Overdrive) == NoteType.Overdrive; }
        }

        #endregion

        #region Methods

        #region Constructor

        /// <summary>
        /// Constructs a new instance of this object
        /// </summary>
        /// <param name="type">a PlayNoteType object defining the general characteristics of this object</param>
        public PlayNote(NoteType type)
            :base(null)
        {
            this.NoteType = type;
            this.TimeCreated = EngineServices.TotalGameTime;

            NormalTexture = new TextureInfo();
            DeadTexture = new TextureInfo();
            PowerTexture = new TextureInfo();
        }

        #endregion

        /// <summary>
        /// Swaps the position of the note over an amout of time in seconds
        /// </summary>
        /// <param name="delta">a float value indicating the amount of time in seconds it should take to swap the position of this note</param>
        public void Swap(float duration)
        {
            if (this.X == 0 || SwapDurationRemaining > 0)
                return;

            SwapDuration = duration;
            SwapDurationRemaining = duration;
            StartPosition = this.X;
            EndingPosition = this.X * -1;
        }

        public void UpdateState(float delta)
        {
            this.Update(delta);
        }

        protected override void Update(float delta)
        {
            #region Set Note Texture

            #region Dead Note

            if (IsDead)
            {
                #region Is Power

                if (IsPower)
                {
                    if (IsHopo)
                    {
                        if (DeadPowerHopoTexture != null)
                        {
                            this.TopTextureCoordinate = DeadPowerHopoTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = DeadPowerHopoTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = DeadPowerHopoTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = DeadPowerHopoTexture.RightTextureCoordinate;
                            this.Texture = DeadPowerHopoTexture.Texture;
                        }
                    }
                    else if (IsTapo)
                    {
                        if (DeadPowerTapoTexture != null)
                        {
                            this.TopTextureCoordinate = DeadPowerTapoTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = DeadPowerTapoTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = DeadPowerTapoTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = DeadPowerTapoTexture.RightTextureCoordinate;
                            this.Texture = DeadPowerTapoTexture.Texture;
                        }
                    }
                    else
                    {
                        if (DeadPowerTexture != null)
                        {
                            this.TopTextureCoordinate = DeadPowerTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = DeadPowerTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = DeadPowerTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = DeadPowerTexture.RightTextureCoordinate;
                            this.Texture = DeadPowerTexture.Texture;
                        }
                    }
                }

                #endregion

                #region Is Hopo

                else if (IsHopo)
                {
                    if (DeadHopoTexture != null)
                    {
                        this.TopTextureCoordinate = DeadHopoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = DeadHopoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = DeadHopoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = DeadHopoTexture.RightTextureCoordinate;
                        this.Texture = DeadHopoTexture.Texture;
                    }
                }

                #endregion

                #region IsTapo

                else if (IsTapo)
                {
                    if (DeadTapoTexture != null)
                    {
                        this.TopTextureCoordinate = DeadTapoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = DeadTapoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = DeadTapoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = DeadTapoTexture.RightTextureCoordinate;
                        this.Texture = DeadTapoTexture.Texture;
                    }
                }

                #endregion

                #region Normal

                else
                {
                    if (DeadTexture != null)
                    {
                        this.TopTextureCoordinate = DeadTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = DeadTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = DeadTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = DeadTexture.RightTextureCoordinate;
                        this.Texture = DeadTexture.Texture;
                    }
                }

                #endregion
            }

            #endregion

            #region Overdrive Note

            else if (IsOverdrive)
            {
                #region Is Power

                if (IsPower)
                {
                    if (IsHopo)
                    {
                        if (OverdrivePowerHopoTexture != null)
                        {
                            this.TopTextureCoordinate = OverdrivePowerHopoTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = OverdrivePowerHopoTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = OverdrivePowerHopoTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = OverdrivePowerHopoTexture.RightTextureCoordinate;
                            this.Texture = OverdrivePowerHopoTexture.Texture;
                        }
                    }
                    else if (IsTapo)
                    {
                        if (OverdrivePowerTapoTexture != null)
                        {
                            this.TopTextureCoordinate = OverdrivePowerTapoTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = OverdrivePowerTapoTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = OverdrivePowerTapoTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = OverdrivePowerTapoTexture.RightTextureCoordinate;
                            this.Texture = OverdrivePowerTapoTexture.Texture;
                        }
                    }
                    else
                    {
                        if (OverdrivePowerTexture != null)
                        {
                            this.TopTextureCoordinate = OverdrivePowerTexture.TopTextureCoordinate;
                            this.BottomTextureCoordinate = OverdrivePowerTexture.BottomTextureCoordinate;
                            this.LeftTextureCoordinate = OverdrivePowerTexture.LeftTextureCoordinate;
                            this.RightTextureCoordinate = OverdrivePowerTexture.RightTextureCoordinate;
                            this.Texture = OverdrivePowerTexture.Texture;
                        }
                    }
                }

                #endregion

                #region Is Hopo

                else if (IsHopo)
                {
                    if (OverdriveHopoTexture != null)
                    {
                        this.TopTextureCoordinate = OverdriveHopoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = OverdriveHopoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = OverdriveHopoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = OverdriveHopoTexture.RightTextureCoordinate;
                        this.Texture = OverdriveHopoTexture.Texture;
                    }
                }

                #endregion

                #region IsTapo

                else if (IsTapo)
                {
                    if (OverdriveTapoTexture != null)
                    {
                        this.TopTextureCoordinate = OverdriveTapoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = OverdriveTapoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = OverdriveTapoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = OverdriveTapoTexture.RightTextureCoordinate;
                        this.Texture = OverdriveTapoTexture.Texture;
                    }
                }

                #endregion

                #region Normal

                else
                {
                    if (OverdriveTexture != null)
                    {
                        this.TopTextureCoordinate = OverdriveTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = OverdriveTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = OverdriveTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = OverdriveTexture.RightTextureCoordinate;
                        this.Texture = OverdriveTexture.Texture;
                    }
                }

                #endregion
            }

            #endregion

            #region Power Note

            else if (IsPower)
            {
                #region Is Hopo

                if (IsHopo)
                {
                    if (PowerHopoTexture != null)
                    {
                        this.TopTextureCoordinate = PowerHopoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = PowerHopoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = PowerHopoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = PowerHopoTexture.RightTextureCoordinate;
                        this.Texture = PowerHopoTexture.Texture;
                    }
                }

                #endregion

                #region IsTapo

                else if (IsTapo)
                {
                    if (PowerTapoTexture != null)
                    {
                        this.TopTextureCoordinate = PowerTapoTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = PowerTapoTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = PowerTapoTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = PowerTapoTexture.RightTextureCoordinate;
                        this.Texture = PowerTapoTexture.Texture;
                    }
                }

                #endregion

                #region Normal

                else
                {
                    if (PowerTexture != null)
                    {
                        this.TopTextureCoordinate = PowerTexture.TopTextureCoordinate;
                        this.BottomTextureCoordinate = PowerTexture.BottomTextureCoordinate;
                        this.LeftTextureCoordinate = PowerTexture.LeftTextureCoordinate;
                        this.RightTextureCoordinate = PowerTexture.RightTextureCoordinate;
                        this.Texture = PowerTexture.Texture;
                    }
                }

                #endregion
            }

            #endregion

            #region Hopo Note

            else if (IsHopo)
            {
                if (HopoTexture != null)
                {
                    this.TopTextureCoordinate = HopoTexture.TopTextureCoordinate;
                    this.BottomTextureCoordinate = HopoTexture.BottomTextureCoordinate;
                    this.LeftTextureCoordinate = HopoTexture.LeftTextureCoordinate;
                    this.RightTextureCoordinate = HopoTexture.RightTextureCoordinate;
                    this.Texture = HopoTexture.Texture;
                }
            }

            #endregion

            #region Tapo Note

            else if (IsTapo)
            {
                if (TapoTexture != null)
                {
                    this.TopTextureCoordinate = TapoTexture.TopTextureCoordinate;
                    this.BottomTextureCoordinate = TapoTexture.BottomTextureCoordinate;
                    this.LeftTextureCoordinate = TapoTexture.LeftTextureCoordinate;
                    this.RightTextureCoordinate = TapoTexture.RightTextureCoordinate;
                    this.Texture = TapoTexture.Texture;
                }
            }

            #endregion

            #region Normal

            else
            {
                if (NormalTexture != null)
                {
                    this.TopTextureCoordinate = NormalTexture.TopTextureCoordinate;
                    this.BottomTextureCoordinate = NormalTexture.BottomTextureCoordinate;
                    this.LeftTextureCoordinate = NormalTexture.LeftTextureCoordinate;
                    this.RightTextureCoordinate = NormalTexture.RightTextureCoordinate;
                    this.Texture = NormalTexture.Texture;
                }
            }

            #endregion

            #endregion

            if (SwapDurationRemaining > 0.0f)
            {
                this.X -= ((StartPosition - EndingPosition) / SwapDuration) * delta;

                SwapDurationRemaining -= delta;

                if (SwapDurationRemaining <= 0)
                    this.X = EndingPosition;
            }

            base.Update(delta);
        }

        #endregion

        private float SwapDuration;
        private float StartPosition;
        private float EndingPosition;
        private float SwapDurationRemaining;
    }
}
